package fr.univ.projet;

import fr.univ.projet.exception.GrilleException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Joueur {

    // Nom du joueur
    private String nom;
    // Mot de passe du joueur
    private String motDePasse;
    
    // Grilles jouées par le joueur
    private Map<Integer, Grille> grilles;

    /**
     * Initialisation du joueur
     * 
     * @param nom nom du joueur
     * @param motDePasse mot de passe du joueur
     */
    public Joueur(String pNom, String pMotDePasse) {
        this.nom = pNom;
        this.motDePasse = pMotDePasse;
        this.grilles = new HashMap<Integer, Grille>();
    }

    /**
     * Ajoute les numéros choisis à la grille
     * 
     * @param lstNum liste des numéros choisis pour la grille
     * @param g grille à laquelle ajouter les numéros
     * @throws GrilleException 
     */
    public void ajouterLesNumerosChoisis(List<Numero> pLstNum, Grille pGrille) throws GrilleException {
        for (Numero num : pLstNum) {
            ajouterUnNumero(num, pGrille);
        }
    }

    /**
     * Ajoute une nouvelle grille
     * 
     * @param pCode code la grille 
     * @param jeu jeu de la grille
     * @return une grille du jeu 
     */
    public Grille ajouterUneGrille(int pCode, Jeu pJeu) {
        Grille g = pJeu.faireGrille(pCode, this);
        grilles.put(pCode, g);

        return g;
    }
    
    /**
     * Ajoute la mise à la grille
     * 
     * @param mise mise pour la grille
     * @param g grille 
     */
    public void ajouterMise(float pMise, Grille pGrille)
    {
        pGrille.setMise(pMise);
    }

    /**
     * Calcule le gain d'une grille
     * 
     * @param codeGrille code la grille 
     * @return gain de la grille
     */
    public float estGagnante(int pCodeGrille) {
        float gain = 0.0f;

        Grille g = grilles.get(pCodeGrille);

        gain = g.getGains();
        return gain;
    }

    /**
     * 
     * @return le gain total de toutes les grilles
     */
    public float gainTotal() {
        float gain = 0.0f;
        List<Grille> listGrilles = new ArrayList<Grille>(grilles.values());

        for (Grille g : listGrilles) {
            gain = gain + g.getGains();
        }

        return gain;
    }

    /**
     * Ajoute un numéro dans la grille
     * 
     * @param pNum numéro à ajouter
     * @param pGrille grille où ajouter le numéro
     * @throws GrilleException 
     */
    private void ajouterUnNumero(Numero pNum, Grille pGrille) throws GrilleException {
        // Vérifie que la grille appartient bien au joueur
        if (this == pGrille.getJoueur()) {
            // Ok c'est bien une grille du joueur

            // Vérifie qu'il y a pas deja trop de numéro choisi
            if (pGrille.getNumerosChoisis().size() < (pGrille.getJeu().getNbreNumero() + pGrille.getJeu().getNbreNumeroChance())) {
                // Le joueur doit encore choisir des numéros
                // Vérifie qu'il peut encore jouer le type de numéro
                if (pNum.isChance() && pGrille.getNbreChance() < pGrille.getJeu().getNbreNumeroChance()) {
                    // Il doit encore jouer au moins un numéro chance
                    pGrille.getNumerosChoisis().add(pNum);
                } else if (pGrille.getNbreSimple() < pGrille.getJeu().getNbreNumero()) {
                    pGrille.getNumerosChoisis().add(pNum);
                } else {
                    throw new GrilleException("Trop de numéro 'simple'!");
                }
            } else {
                throw new GrilleException("Trop de numéros choisis");
            }
        } else {
            throw new GrilleException("Mauvais joueur pour cette grille");
        }
    }

    /**
     * 
     * @return  le nom du joueur
     */
    public String getNom() {
        return nom;
    }

    /**
     * 
     * @return  le mot de passe du joueur
     */
    public String getMotDePasse() {
        return motDePasse;
    }
    
    /**
     * 
     * @return les grilles jouées par le joueur
     */
    public Map<Integer, Grille> getGrilles() {
        return grilles;
    }

    @Override
    public boolean equals(Object pObj) {
        if (pObj == null) {
            return false;
        }
        if (getClass() != pObj.getClass()) {
            return false;
        }
        final Joueur other = (Joueur) pObj;
        if ((this.nom == null) ? (other.nom != null) : !this.nom.equals(other.nom)) {
            return false;
        }
        if ((this.motDePasse == null) ? (other.motDePasse != null) : !this.motDePasse.equals(other.motDePasse)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 43 * hash + (this.nom != null ? this.nom.hashCode() : 0);
        hash = 43 * hash + (this.motDePasse != null ? this.motDePasse.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return nom;
    }    
}
